
#include <BReadWrite>
#include <BCursor>
#include <BPainter>
#include <BMouseEvent>
#include <BStyle>
#include <BFile>

#include "StyleEdit.h"

StyleEdit::StyleEdit(BWidget* parent) : BTextEdit(parent)
{
	BImage* image = ReadFile<BImage>("data/image/Multimedia_Icons_005.png");
	BCursor* cursor = new BCursor();
	cursor->setImage(image);
	cursor->setPoint(-9, 0);
	cursor->setSize(17, 19);
	//this->setCursor(cursor);

	connect(this, Signal_TextChanged, &StyleEdit::slotTextChanged);
	connect(this, Signal_TextEdited, &StyleEdit::slotTextEdited);
}
StyleEdit::~StyleEdit()
{

}

void StyleEdit::setFileName(const BString& fileName)
{
	if (_fileName != fileName)
	{
		_fileName = fileName;
	}
}
const BString& StyleEdit::fileName() const
{
	return _fileName;
}

bool StyleEdit::load()
{
	BFile file(_fileName);
	if (file.open(IO_Read))
	{
		BString text;
		file.read(text);
		return this->setText(text);
	}
	return false;
}
bool StyleEdit::save() const
{
	BFile file(_fileName);
	if(file.open(IO_Write))
	{
		const BString& text = this->text();
		return file.write(text);
	}
	return false;
}

void StyleEdit::syntax()
{
	StyleFormat* format = (StyleFormat*)this->format();
	if (!format)
	{
		format = new StyleFormat();
		this->setFormat(format);
	}
	format->reset();
	const BString& text = this->text();
	BString str;
	for (auto it = text.begin(); it.valid(); ++it)
	{
		if (it == '{')
		{
			StyleFormat::Node& node = format->insert(it.count() - str.count(), it.count());
			node.font = _nameFont;
			node.color.set(50, 100, 150);
			str.clear();
			continue;
		}
		if (it == ':')
		{
			StyleFormat::Node& node = format->insert(it.count() - str.count(), it.count());
			node.font = _signFont;
			str.trimmed();
			if (str.beginWith('*'))
				node.color.set(100, 150, 50);
			else
				node.color.set(0, 0, 0);
			str.clear();
			continue;
		}
		if (it == ';')
		{
			StyleFormat::Node& node = format->insert(it.count() - str.count(), it.count());
			node.font = _signFont;
			node.color.set(150, 100, 50);
			str.clear();
			continue;
		}
		if (it == '/' && (it + 1) == '*')
		{
			int end = text.find("*/", it.index());
			StyleFormat::Node& node = format->insert(it.count() - str.count(), end);
			node.end = it.count();
			node.font = _noteFont;
			node.color.set(50, 100, 120);
			str.clear();		
			continue;
		}
		str.append(*it);
	}

}

void StyleEdit::slotTextChanged()
{
	const BString& text = this->text();
	syntax();
}
void StyleEdit::slotTextEdited()
{
	const BString& text = this->text();
	syntax();
}

void StyleEdit::styleEvent(const BEvent& event)
{
	BTextEdit::styleEvent(event);
	const BStyle* style = event.value();
	_nameFont = style->font();
	_signFont = style->font();
}
